Having to make the hint of the week, I start with the kind of warriors I like more and I can do better, replicators, or paper; the sort of warrior that use the sheer number to overcome the enemy.
Paper warriors, like every other, have evoluted a lot from the beginnings of the game; presently they use almost all the so called 'silk' style, i.e. splitting before copying. This can be done only under 94 rules because requires post increment and a-field addressing. Now let's give a look at a very simple guy.
start spl 1
mov -1, 0 ;generate 3 parallel processes
1 silk spl.a @0, 100 ;split
2 mov.i }silk, >silk ;copy
3 jmp.a silk, {silk ;repeat the thing resetting pointer
First two lines generate 3 processes that execute the same line one after the other, before executing the next. First line creates another process to execute line start+1, then process 1 copy start line over the mov and process two splits, adding another process to execute silk. The simpler way to generate an exact number of parallel processes is converting the number required in binary 3 -> 11, subtract one -> 10, use a spl 1 for every one and a mov -1,0 for every zero. Much simpler to do than to tell. For the warrior to work we need at least as many processes as we have lines to copy.
Let's go back toour warrior; now we have three processes executing line 1 they split, where, at the a-field address i.e. the address pointed by b-field of line 0 locations away, the b-field of the line they are executing, 100 locations away. When all three process executed this line we have three others process ready to execute line silk+100, there is nothing to execute here but we have some time because new generated processes are queued after those executing the split.
First three processes now execute line 2, they move what's pointed by a-field of line 1 to the location pointed by b-field of line 1 then they increment both a and b field of line 1. First process moves line 1 100 cells away from line 1 and leaves line 1 changed such a way:
1 silk spl.a @1, 101
so it copyes line 2 101 cells away from silk, just after the previous line. Process 3 does same thing copying line3.
Now it's the turn of the new processes, those created by line1, to execute, they are not more sitting on an empty cell but over the copy of line1 created by line2, they execute it and begin creating third generation copy.
First three processes now reach line3, now the warrior has modifyed in such way
1 silk spl.a @3, 102
2 mov.i }silk, >silk
3 jmp.a silk, {silk
The a-field of line 3 is the address of the jump while b-field decrements a-field of line 1 so that the warrior can go on splitting and copying.
This one is not a real warrior, his offensive potential is too small, it's just to understand how a silk replicator works. Simple improvements are adding an add line so as copies are not packed one near the other, and adding some bombing to make it a bit nastier. The warrior following is Paperone, my first warrior to enter 94 hill, it was on top of beginner hill for some time a few months ago.
It's similar to the example in the FAQ (very similar indeed :-) but to make it run well I had to work on the many constants.
;redcode-94
;name Paperone
;author Beppe Bezzi
;strategy Silk replicator
;kill Paperone
;assert CORESIZE == 8000
start spl 1, <300 ;\
spl 1, <150 ; generate 7 consecutive processes
mov -1, 0 ;/
silk spl 3620, #0 ;split to new copy
mov.i >-1, }-1 ;copy self to new location
;this is another way to copy using multiple processes, the other one is a bit better because we can decrement the cell we are splitting to and, if we are lucky, kill an imp.
mov.i bomb, >2005 ;linear bombing
mov.i bomb, }2042 ;A-indirect bombing for anti-vamp
;The first bomb laid down acts as a pointer for the following stream, laying down a carpet.
add.a #50, silk ;distance new copy
jmp silk, <silk ;reset source pointer, make new copy
bomb dat.f >2667, >5334 ;anti-imp bomb
This is very effective against 3 points imp rings. A lucky hit on the executing process can kill many others; other kinds of bombs are used, by me at least, we'll discuss them another time.
Another time we'll discuss more advanced questions: another replicating engine, that is better than this one, and some other paper related topics like spread constants, bombs, strategies...
---
Replicators (part 2)
Hi, happy to see you again.
Last time we spoke of basic replicator concepts, now I'll try to speak of some advanced topics.
To begin let's give a look at another replicating engine, the best one in my opinion, first introduced by Jippo Pohjalainen in its warrior Timescape.
We report slightly simplified, the way it has been proposed as White warrior by Nandor and Stefan in the tournament.
warrior
spl 1, <-200
mov.i -1, 0 ;this block generates 6 processes
spl 1, <-300
tim2 spl @tim2, }TSTEP
tim2a mov.i }tim2, >tim2
cel2 spl @cel2, }CSTEP ;these four lines are the main body
cel2a mov.i }cel2, >cel2
;here you can insert some bombing line
ncl2a mov.i {cel2, <ncl2
ncl2 jmp @ncl2, >NSTEP
All you know, having read part 1, how the first four lines work, they split away and copy the warrior body where the processes are going to execute, is worth noting that the lines cel2, cel2a don't copy the warrior from the beginning but copy two blank lines in the bottom, after ncl2.
Line ncl2a copies again the warrior, fron cel2 to ncl2+2, backward because of the pre decrements and last line jumps to the beginning of this copy resetting the pointer.
The main advantage of this structure is that all the code is executed but once, to be left as a decoy to foul scanners; this is a great advantage compared with the older structure of the first hint. Another advantage is that the warrior will continue to work, slowed, even if wounded by a bomb in its last two lines.
This guy was the harder thing to kill before Paul Kline created Die Hard.
With this structure have been made some others replicators of success, worth mention are Nobody special by Mike Nonemacher and Marcia Trionfale by...me.
Now we have a solid structure to work on, to make it deadlier we can add some other form of attack than overwriting our opponent. The original Timescape has this single bombing line inserted after cel2a:
mov.i <-FSTEP,{FSTEP
how it works, remember we have some processes working in papallel:
every process takes the cell -FSTEP away, decrements its b-field, take the cell pointed by and moves it in the position pointed by the decremented a-field of the cell FSTEP cells away. Simple? NO! :-)
OK. From the beginning:
dat 0,0
-FSTEP dat 0,0 ;will became dat 0,-1
...
mov.i <-FSTEP,{FSTEP ;here we are
...
begin mov bomb, nearme
... [enemy code] ;Our enemy is here, we are lucky :-)
end jmp begin
dat 0,0
FSTEP dat 0,0 ;will became dat -1,0
Now 1st process takes the cell -FSTEP and decrements its b-field, takes the cell pointed by the decremented b-field (in the example the cell before) and moves it; where? It takes the cell FSTEP and decrements its a-field thake the cell pointed by it, here he hits. Missed, don't worry we have process 2 taking cell -FSTEP-2 and moving it at FSTEP-2 and so on till we have processes executing the bombing line. At the end the enemy is no more, in the example at least.
Bombing is useful not only to get rid of our enemy but also to get rid of ourself ... yes, enemy scanners have